/*
 * @Description: 
 * @FilePath: /STM32/USER/bsp/gpio.c
 * @Author: Wei Zhou
 * @Github: https://github.com/zromyk
 * @Date: 2021-04-28 15:25:19
 * @LastEditors: Wei Zhou
 * @LastEditTime: 2021-04-28 15:25:19
 * @Copyright: Copyright  2017 muyiro. All rights reserved.
 */
 
#include "gpio.h"
#include "rcc.h"

static GPIO_TypeDef* GPIOx_BASE[] = 
{
    GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH, 
    GPIOI, GPIOJ, GPIOK
};

void gpio_out_init(PIN_Dev pin, GPIOPuPd_TypeDef PuPd, uint16_t bit)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_TypeDef* GPIOx     = GPIOx_BASE[getGPIO(pin)];
    uint16_t GPIO_Pin       = (((uint16_t)GPIO_Pin_0) << getPIN(pin));
    uint32_t RCC_AHB1Periph = (((uint32_t)RCC_AHB1Periph_GPIOA) << getGPIO(pin));

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph, ENABLE);
    
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = PuPd;
    GPIO_Init(GPIOx, &GPIO_InitStruct);

    if (bit) { GPIO_SetBits  (GPIOx, GPIO_Pin); }
    else     { GPIO_ResetBits(GPIOx, GPIO_Pin); }
}

void gpio_in_init(PIN_Dev pin, GPIOPuPd_TypeDef PuPd)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_TypeDef* GPIOx     = GPIOx_BASE[getGPIO(pin)];
    uint16_t GPIO_Pin       = (((uint16_t)GPIO_Pin_0) << getPIN(pin));
    uint32_t RCC_AHB1Periph = (((uint32_t)RCC_AHB1Periph_GPIOA) << getGPIO(pin));

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph, ENABLE);
    
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStruct.GPIO_PuPd = PuPd;
    GPIO_Init(GPIOx, &GPIO_InitStruct);
}

void gpio_af_init(PIN_Dev pin, GPIOPuPd_TypeDef PuPd, uint8_t GPIO_AF)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_TypeDef* GPIOx     = GPIOx_BASE[getGPIO(pin)];
    uint16_t GPIO_Pin       = (((uint16_t)GPIO_Pin_0) << getPIN(pin));
    uint32_t RCC_AHB1Periph = (((uint32_t)RCC_AHB1Periph_GPIOA) << getGPIO(pin));
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph, ENABLE);
    GPIO_PinAFConfig(GPIOx, getPIN(pin), GPIO_AF);
    
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = PuPd;
    GPIO_Init(GPIOx, &GPIO_InitStruct);
}

void gpio_an_init(PIN_Dev pin)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_TypeDef* GPIOx     = GPIOx_BASE[getGPIO(pin)];
    uint16_t GPIO_Pin       = (((uint16_t)GPIO_Pin_0) << getPIN(pin));
    uint32_t RCC_AHB1Periph = (((uint32_t)RCC_AHB1Periph_GPIOA) << getGPIO(pin));
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph, ENABLE);
    
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOx, &GPIO_InitStruct);
}

void gpio_write(PIN_Dev pin, uint8_t bit)
{
    GPIO_TypeDef* GPIOx     = GPIOx_BASE[getGPIO(pin)];
    uint16_t GPIO_Pin       = (((uint16_t)GPIO_Pin_0) << getPIN(pin));
    
    if (bit) { GPIO_SetBits  (GPIOx, GPIO_Pin); }
    else     { GPIO_ResetBits(GPIOx, GPIO_Pin); }
}

uint8_t gpio_read(PIN_Dev pin)
{
    GPIO_TypeDef* GPIOx     = GPIOx_BASE[getGPIO(pin)];
    uint16_t GPIO_Pin       = (((uint16_t)GPIO_Pin_0) << getPIN(pin));
    
    return GPIO_ReadInputDataBit (GPIOx, GPIO_Pin);
}

